﻿using System;
using System.Linq;

namespace FranceTriple.Dal
{
    public class ForumTopicDal
    {
        public static Int32 GetTopicIdByPostId(int PostId)
        {
            Int32 topicId;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    topicId = (from p in ctx.ForumPostSet.Include("ForumTopic")
                               where (p.Id == PostId)
                               select p.ForumTopic.Id).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "GetTopicIdByPostId", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
            return topicId;
        }

        public static Int32 GetTopicIdByPollId(int PollId)
        {
            Int32 topicId;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    topicId = (from p in ctx.PollSet.Include("ForumTopic")
                               where (p.Id == PollId)
                                  select p.ForumTopic.Id).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "GetTopicIdByPollId", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
            return topicId;
        }

        public static void LockEntity(Int32 entityID)
        {
            ForumTopic thisTopic;
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    thisTopic = (from t in ctx.ForumTopicSet
                                 where (t.Id == entityID)
                                 select t).FirstOrDefault();
                    thisTopic.IsUnlocked = false; ;
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("UpdateError".ToLocalizedString(), "LockEntity", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
        }

        public static void UnlockEntity(Int32 entityID)
        {
            ForumTopic thisTopic;
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    thisTopic = (from t in ctx.ForumTopicSet
                                 where (t.Id == entityID)
                                 select t).FirstOrDefault();
                    thisTopic.IsUnlocked = true; ;
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("UpdateError".ToLocalizedString(), "UnlockEntity", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
        }

        public static void IncrementNumberOfRead(Int32 entityID)
        {
            ForumTopic thisTopic;
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    thisTopic = (from t in ctx.ForumTopicSet
                                 where (t.Id == entityID)
                                 select t).FirstOrDefault();
                    thisTopic.NumberHasBeenSeenForumTopic++;
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("UpdateError".ToLocalizedString(), "IncrementNumberOfRead", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
        }

        public static ForumTopic GetEntity(Int32 entityID)
        {
            ForumTopic fTopic;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    fTopic = (from t in ctx.ForumTopicSet
                              where (t.Id == entityID)
                              select t).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumTopic", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
            return fTopic;
        }

        public static int CreateEntity(ForumTopic entity)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    //Décaler à partir de la nouvelle position pour créer une place
                    if (entity.OrderForumTopic > 0)
                    {
                        foreach (ForumTopic t in ctx.ForumTopicSet.Include("ForumCategory").Where(t1 => (t1.OrderForumTopic > 0) && (t1.OrderForumTopic >= entity.OrderForumTopic)))
                        {
                            if (t.ForumCategory.Id == entity.ForumCategory.Id)
                                t.OrderForumTopic = t.OrderForumTopic + 10;
                        }
                    }
                    ForumTopic myTopic = new ForumTopic();
                    myTopic.LabelForumTopic = entity.LabelForumTopic;
                    myTopic.AuthorForumTopic = entity.AuthorForumTopic;
                    myTopic.OrderForumTopic = entity.OrderForumTopic;

                    // A Activer uniquement pour les imports
                    //myTopic.CreationDateForumTopic = entity.CreationDateForumTopic;

                    myTopic.IsUnlocked = entity.IsUnlocked;
                    myTopic.NumberHasBeenSeenForumTopic = entity.NumberHasBeenSeenForumTopic;

                    ctx.AddToForumTopicSet(myTopic);
                    myTopic.ForumCategory = (ForumCategory)ctx.GetObjectByKey(entity.ForumCategory.EntityKey);
                    myTopic.ForumCategory.NumberOfTopic++;
                    ctx.SaveChanges();
                    return myTopic.Id;
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("InsertError".ToLocalizedString(), "ForumTopic", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
        }

        public static void UpdateEntity(ForumTopic entity)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    var topicToUpdate = ctx.ForumTopicSet.Where(t => t.Id == entity.Id).FirstOrDefault();
                    if (topicToUpdate == null)
                    {
                        CreateEntity(entity);
                        return;
                    }

                    // Le sujet change de catégorie
                    if (ForumCategoryDal.GetCategoryIdByTopicId(topicToUpdate.Id) != entity.ForumCategory.Id)
                    {
                        //Mémoriser la catégorie de départ
                        var oldCategoryId = ForumCategoryDal.GetCategoryIdByTopicId(topicToUpdate.Id);

                        topicToUpdate.ForumCategory = (ForumCategory)ctx.GetObjectByKey(ForumCategoryDal.GetEntity(entity.ForumCategory.Id).EntityKey);
                        if (entity.OrderForumTopic > 0)
                            entity.OrderForumTopic = (from t in ctx.ForumTopicSet.Include("ForumCategory").Where(t1 => t1.ForumCategory.Id == entity.ForumCategory.Id)
                                                      select t.OrderForumTopic).DefaultIfEmpty().Max() + 10;
                        ctx.SaveChanges();

                        //Mettre à jour les compteurs de la catégorie de départ
                        ForumCategoryDal.InitializeCategoryCounter(oldCategoryId);
                        //Mettre à jour les compteurs de la catégorie d'arrivée
                        ForumCategoryDal.InitializeCategoryCounter(topicToUpdate.ForumCategory.Id);
                    }
                    // Ordre de tri des sujets sticky dans la même catégorie
                    else if (topicToUpdate.OrderForumTopic != entity.OrderForumTopic)
                    {
                        //Utiliser la place libérée par le déplacement
                        if (topicToUpdate.OrderForumTopic > 0)
                        {
                            foreach (ForumTopic t in ctx.ForumTopicSet.Include("ForumCategory").Where(t1 => (t1.ForumCategory.Id == entity.ForumCategory.Id)
                                && (t1.OrderForumTopic > 0)
                                && (t1.OrderForumTopic > topicToUpdate.OrderForumTopic)))
                            {
                                t.OrderForumTopic -= 10;
                            }
                        }
                        ctx.SaveChanges();

                        Boolean OrderTopicAlreadyExists = (from t in ctx.ForumTopicSet.Where(t2 => t2.OrderForumTopic == entity.OrderForumTopic) select t.OrderForumTopic).FirstOrDefault() > 0;
                        //Décaler à partir de la nouvelle position pour créer une place
                        if (OrderTopicAlreadyExists)
                        {
                            entity.OrderForumTopic += 10;
                            foreach (ForumTopic t in ctx.ForumTopicSet.Include("ForumCategory").Where(t1 => (t1.ForumCategory.Id == entity.ForumCategory.Id)
                                && (t1.OrderForumTopic > 0)
                                && (t1.OrderForumTopic >= entity.OrderForumTopic)))
                            {
                                t.OrderForumTopic += 10;
                            }
                        }
                    }

                    topicToUpdate.LabelForumTopic = entity.LabelForumTopic;
                    topicToUpdate.OrderForumTopic = entity.OrderForumTopic;

                    // Ces éléments sont mis à jour par d'autres fonctions.
                    //topicToUpdate.AuthorForumTopic = entity.AuthorForumTopic;
                    //topicToUpdate.NumberHasBeenSeenForumTopic = entity.NumberHasBeenSeenForumTopic;
                    //topicToUpdate.IsUnlocked = entity.IsUnlocked;

                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("UpdateError".ToLocalizedString(), "ForumTopic", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
        }

        public static void DeleteEntity(int entityID)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    var topicToUpdate = ctx.ForumTopicSet.Include("ForumCategory").Where(t => t.Id == entityID).FirstOrDefault();
                    if (topicToUpdate == null)
                        return;

                    topicToUpdate.ForumCategory.NumberOfTopic--;

                    ctx.ForumTopicSet.DeleteObject(topicToUpdate);

                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("DeleteError".ToLocalizedString(), "ForumTopic", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
        }

        public static ForumTopic[] GetEntities(string searchText)
        {
            ForumTopic[] res;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    res = (from t in ctx.ForumTopicSet
                           where t.LabelForumTopic.Contains(searchText) |
                                        t.AuthorForumTopic.Contains(searchText)
                           orderby t.OrderForumTopic, t.LabelForumTopic
                           select t).ToArray();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumTopic", ex.Message), ex) { EntityType = typeof(ForumTopic) };
            }
            return res;
        }
    }
}
